#ifndef __INPUTIMAGE_H__
#define __INPUTIMAGE_H__

#include <opencv/highgui.h>
#include <vector>
#include <string>
#include <boost/smart_ptr.hpp>

namespace cshotel {
    class ImageFeature;
    class ImageMatch;
    
    typedef cv::Size_<double> Size2d;
    
    class InputImage {
    public:
        InputImage(const std::string& name, const cv::Size2i& size, const std::string& matchingVersionName, double scaleFactor, int newId);
        ~InputImage();
        
        boost::shared_ptr<cv::Mat> getImage();
        boost::shared_ptr<cv::Mat> getMatchingVersionImage();
        const std::string& getName() const;
        const std::string& getMatchingVersionName() const;
        int getId() const;
        const cv::Size2i& getImageSize();
        
        const std::vector<boost::shared_ptr<ImageFeature> >& getImageFeatures() const;
        void addImageFeature(boost::shared_ptr<ImageFeature> feature);
        
        const std::vector<boost::shared_ptr<ImageMatch> >& getImageMatches() const;
        void addImageMatch(boost::shared_ptr<ImageMatch> newMatch);
        
        cv::Mat getGlobalHomography() const;
        cv::Mat getMatchingVersionHomography() const;
        void setMatchingVersionHomography(const cv::Mat& homography);
        
        void setTransformedVersion(const std::string& fileName);
        const std::string& getTransformedVersionFileName();
        const cv::Point2d& getTransformedVersionOffset();
        const Size2d& getTransformedVersionImageSize();
        
        static int getImageId(boost::weak_ptr<InputImage> img);
        static void drawFeatureMatchImage(boost::weak_ptr<InputImage> image1, boost::weak_ptr<InputImage> image2, const std::vector<std::pair<boost::weak_ptr<ImageFeature>, boost::weak_ptr<ImageFeature> > >& features, std::string prefix);
        static void writeDebugImages(boost::weak_ptr<InputImage> img);
    
    private:
        // original input file name
        std::string fileName;
        // file name of the scaled down version for feature extraction
        std::string matchingVersionFileName;
        // file name of the transformed version of the input image (homography applied)
        std::string transformedVersionFileName;
        boost::weak_ptr<cv::Mat> image;
        boost::weak_ptr<cv::Mat> matchingVersionImage;
        int id;
        std::vector<boost::shared_ptr<ImageFeature> > features;
        std::vector<boost::shared_ptr<ImageMatch> > matches;
        cv::Mat matchingVersionHomography;
        double matchingVersionScaleFactor;
        int transformedVersionOffsetX;
        int transformedVersionOffsetY;
        cv::Size2i imageSize;
        Size2d transformedVersionImageSize;
        cv::Point2d transformedVersionOffset;
        
        void calculateTransformedSizeAndOffset();
    };
}

#endif
